(function () {
    //view视图对象
    function View(_target, template) {
        this.scriptTarget = _target;
        this.template = Handlebars.compile(template);
        this.scriptTarget.data("view", this);
        this.data;
    }

    //hbs实现视图对象
    $.extend(View.prototype, {
        clear: function () {
            this.target.remove();
            this.target = null;
            delete this.data;
        },
        refresh: function (data) {
            if (!!this.target)this.target.remove();
            this.compile(data || this.data);
        },
        compile: function (data) {
            this.data = data;
            this.target = $(this.template(this.data));
            this.target.initialize();
            this.scriptTarget.after(this.target).hide();
            this.scriptTarget.triggerHandler("complete", this);
        }
    });
    //绘制模版
    View.draw = function (data) {
        var view;
        //判断是刷新还是创建
        if (!$(this).data("view")) {
            var target = $(this).html();
            view = new View($(this), target);
            $(this).data("view", view);
            view.compile(data);
        } else {
            view = $(this).data("view");
            view.refresh(data);
        }
        if (!!data)view.data = data;
    }

    //view视图对象插件
    $.fn.view = function (data) {
        if (!data) data = [];
        if ($(this).length == 0) {
            throw new Error("未找到jquery对象")
        }
        $(this).on('complete', function (e, view) {
            view.target.find('[data-index-replace-json]').add(view.target.filter('[data-index-replace-json]')).each(function () {
                $(this).data('json', !!view.data.rows ? view.data.rows[$(this).data('index-replace-json')] : view.data[$(this).data('index-replace-json')]);
            });
        });

        View.draw.apply(this, [data]);
        return $(this);
    };
})();

//hbs插件
var helpers = {
    string: function (d) {
        return !!d ? JSON.stringify(d) : '{}';
    },
    addIndex: function (number) {
        return number + 1;
    },
    is: function (value, test, options) {
        if (value === test) {
            return options.fn(this);
        } else {
            return options.inverse(this);
        }
    },
    compare: function (left, operator, right, options) {
        /*jshint eqeqeq: false*/

        if (arguments.length < 3) {
            throw new Error('Handlebars Helper "compare" needs 2 parameters');
        }

        if (options === undefined) {
            options = right;
            right = operator;
            operator = '===';
        }

        var operators = {
            '==': function (l, r) {
                return l == r;
            },
            '===': function (l, r) {
                return l === r;
            },
            '!=': function (l, r) {
                return l != r;
            },
            '!==': function (l, r) {
                return l !== r;
            },
            '<': function (l, r) {
                return l < r;
            },
            '>': function (l, r) {
                return l > r;
            },
            '<=': function (l, r) {
                return l <= r;
            },
            '>=': function (l, r) {
                return l >= r;
            },
            'typeof': function (l, r) {
                return typeof l == r;
            }
        };

        if (!operators[operator]) {
            throw new Error('Handlebars Helper "compare" doesn\'t know the operator ' + operator);
        }

        var result = operators[operator](left, right);

        if (result) {
            return options.fn(this);
        } else {
            return options.inverse(this);
        }
    },
    argToArray: function (data) {
        var array = [];
        var i = 0;
        do {
            array.push(data[i]);
            i++;
        } while (data[i] != undefined);
        return array;
    },
    eval: function () {
        var array = helpers.argToArray(arguments);
        array.pop();
        return eval(array.join(''));
    },
    evalif: function () {
        var options = arguments[arguments.length - 1];
        var array = helpers.argToArray(arguments);
        array.pop();
        var result = eval(array.join(''));
        if (result) {
            return options.fn(this);
        } else {
            return options.inverse(this);
        }
    },
    addZeroLeft: function (value, resultLength) {
        var result = value.toString();
        if (result.length < resultLength) {
            var i = result.length;
            while (i++ < resultLength) {
                result = "0" + result;
                if (result.length == resultLength)
                    break;
            }
        }
        return result;
    },
    empty: function (value, options) {
        if (!value || value.length == 0) {
            return options.fn(this);
        } else {
            return options.inverse(this);
        }
    },
    replaceAll: function (value, raRegExp, replaceText) {
        if (typeof raRegExp == "undefined" || raRegExp == null)
            return;
        if (!( raRegExp instanceof RegExp))
            raRegExp = new RegExp(raRegExp, "g");
        return value.replace(raRegExp, replaceText);
    },
    defaultvalue: function (d, el) {
        if (!!d) return d;
        return el;
    },
    date: function (date, formatter) {
        return Date.format(date, formatter);
    },
    subString: function (size, value, moreStr) {
        if (value.length >= (size + moreStr.length)) {
            return value.substring(0, size) + moreStr;
        }
        return value;
    },
    addPercentage: function () {
        var array = helpers.argToArray(arguments);
        var shift = array.shift();
        array.pop();
        var count = 0;
        for (var i = 0; i < array.length; i++) {
            count += array[i] * 1;
        }
        if (isNaN(count) || count == 0) return 0;
        return (shift / count).toFixed(4) * 100;
    },
    fixed: function (number, size) {
        number = number * 1;
        if (isNaN(number)) return "";
        return (number).toFixed(size * 1);
    }
};
Handlebars.registerHelper(helpers);